//
// Created by Scott_Z on 2025/4/16.
//
const int TASK_MAX_THRESHHOLD=1024;
#include "../include/treadpool.h"

ThreadPool::ThreadPool()
            :initThreadSize_(0)
            ,taskSize_(0)
            ,taskQueMaxThreshHold_(TASK_MAX_THRESHHOLD)
            ,poolMode_(PoolMode::MODE_FIEED)
{}


ThreadPool::~ThreadPool()
{}


//设置线程池工作模式
void ThreadPool::setMode(PoolMode poolMode)
{
    poolMode_=poolMode;
}

//设置task任务队列上线阈值
void ThreadPool::setTaskQueMaxThreshHold(int threshHold)
{
    taskQueMaxThreshHold_=threshHold;
}

//给线程池提交任务
void ThreadPool::submitTask(std::shared_ptr<Task> sp)
{
    //获取锁
    std::unique_lock<std::mutex> lock(taskQueMtx_);
    //线程的通信  等待
//    while(taskQue_.size()==taskQueMaxThreshHold_)
//    {
//        notFull_.wait(lock);
//    }

    //该行代码如上
    /*
     * 用户提交任务，最长不能阻塞1s，否则判断提交任务失败，返回
        wait()一直等待，wait_for() wait_until加时间参数，
        wait_for() 等待时常
        wait_until 直到——
     */
    if (notFull_.wait_for(lock,std::chrono::seconds (1),[&]()->bool {return taskQue_.size()<(size_t)taskQueMaxThreshHold_; }))
    {
        std::cerr<<"task queue is full,submit task fail"<<std::endl;
        return;
    }

    //如果有空余，把任务放入任务队列中
    taskQue_.emplace(sp);
    taskSize_++;

    //因为新放了任务，任务队列肯定不空，在notEmpty_上通知
    notEmpty_.notify_all();
}
//开启线程池
void ThreadPool::start(int initThreadSize)
{
    //记录线程初试个数
    initThreadSize_=initThreadSize;

    //创建线程对象
    for(int i=0;i<initThreadSize_;i++)
    {
        //创建thread线程对象的时候,吧线程函数给到thread线程对象
        auto ptr=std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc,this));
        threads_.emplace_back(std::move(ptr));
    }

    //启动所有线程
    for(int i=0;i<initThreadSize_;i++)
    {
        threads_[i]->start();//需要去执行一个线程函数
    }
}


Thread::Thread(ThreadFunc func):func_(func){

}

Thread::~Thread(){

}

//消费任务池
void ThreadPool::threadFunc()
{
    /*std::cout<<"begin threadFunc"<<std::this_thread::get_id()<<std::endl;
    std::cout<<"end threadFunc"<<std::this_thread::get_id()<<std::endl;*/
    for(;;)
    {
        std::shared_ptr<Task> task;
        {
            //先获取锁
            std::unique_lock<std::mutex> lock(taskQueMtx_);
            //等待notempty条件
            notEmpty_.wait(lock,[&]()->bool {return  taskQue_.size()>0;});
            //从任务队列中取一个任务
            auto task=taskQue_.front();
            taskQue_.pop();
            taskSize_--;

            //如果依然有任务，继续通知其他线程执行任务
            if (taskQue_.size()>0)
            {
                notEmpty_.notify_all();
            }
            //取出一个任务，进行通知
            notFull_.notify_all();
        }
        //应该把锁释放掉

        //当前线程负责执行这个任务
        if (task!= nullptr)
        {
            task->run();
        }
    }
}

void Thread::start()
{
    //创建一个线程来执行一个线程函数
    std::thread t(func_);
    t.detach();//设置分离线程
}